<template>
  <div class="post-list" ref="postListContainer">
    <div v-if="posts.length === 0 && !loading" class="empty-state">
      <van-icon name="description" size="60" color="#ccc" />
      <p>暂无内容</p>
    </div>

    <template v-else>
      <van-cell-group
          v-for="post in posts"
          :key="post.postId"
          inset
          class="post-card"
          @click="handlePostClick(post.postId)"
      >
        <div>
          <div class="post-header">
            <van-image round width="45" height="45" :src="post.user.avatar" />
            <div class="post-user-info">
              <div class="post-user-name">
                {{ post.user.nickname }}
                <van-tag v-if="post.tag" type="primary" size="mini">{{ post.tag }}</van-tag>
              </div>
              <div class="post-time">{{ post.createdAt }}</div>
            </div>
          </div>
          <div class="post-title">{{ post.title }}</div>
          <div class="post-content">{{ post.content }}</div>
          <div class="post-footer">
            <div class="post-action like" @click.stop="handleAction(post, 'like')">
              <van-icon
                  :name="post.isLiked ? 'like' : 'like-o'"
                  size="20"
                  :color="post.isLiked ? '#ff5000' : ''"
              />
              <span>{{ post.likeCount }}</span>
            </div>
            <div class="post-action comment" @click.stop="handleComment(post.postId)">
              <van-icon name="comment-o" size="20" />
              <span>{{ post.replyCount }}</span>
            </div>
            <div class="post-action collect" @click.stop="handleAction(post, 'collect')">
              <van-icon
                  :name="post.isCollected ? 'star' : 'star-o'"
                  size="20"
                  :color="post.isCollected ? '#ffd800' : ''"
              />
              <span>{{ post.collectCount }}</span>
            </div>
          </div>
        </div>
      </van-cell-group>

      <div v-if="loading" class="loading-indicator">
        <van-loading size="24px">加载中...</van-loading>
      </div>

      <div v-if="!hasMore && posts.length > 0" class="no-more-data">
        <van-divider>已经到底了</van-divider>
      </div>
    </template>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import { Loading, Divider, showToast } from 'vant';
import axios from '@/utils/axios';
import router from "@/router/index";

const props = defineProps({
  posts: {
    type: Array,
    default: () => [],
  },
  loading: {
    type: Boolean,
    default: false,
  },
  hasMore: {
    type: Boolean,
    default: true,
  },
});

const emit = defineEmits(['load-more', 'post-click', 'update-post']);

const postListContainer = ref(null);
let scrollHandler = null;
let isCheckingScroll = false;

// Handles like or collect actions with optimistic UI updates and rollback on failure
const handleAction = async (post, type) => {
  const isActioned = type === 'like' ? post.isLiked : post.isCollected;
  const countKey = type === 'like' ? 'likeCount' : 'collectCount';
  const stateKey = type === 'like' ? 'isLiked' : 'isCollected';
  const apiEndpoint = `/api/posts/${post.postId}/${type}`;
  const successMsg = type === 'like' ? '点赞成功' : '收藏成功';
  const cancelMsg = type === 'like' ? '已取消点赞' : '已取消收藏';

  // Optimistic UI update
  const wasActioned = isActioned;
  post[stateKey] = !wasActioned;
  post[countKey] += wasActioned ? -1 : 1;

  try {
    const response = await axios.post(apiEndpoint, {
      action: !wasActioned,
    });
    if (response.code !== 200) {
      // Rollback on API failure
      post[stateKey] = wasActioned;
      post[countKey] += wasActioned ? 1 : -1;
      showToast(response.msg || '操作失败');
      return;
    }
    // Final state update from API response
    post[stateKey] = response.data;
    emit('update-post', {
      postId: post.postId,
      [stateKey]: response.data,
      [countKey]: post[countKey],
    });
    showToast(post[stateKey] ? successMsg : cancelMsg);
  } catch (error) {
    console.error(`${type} operation failed:`, error);
    // Rollback on network error
    post[stateKey] = wasActioned;
    post[countKey] += wasActioned ? 1 : -1;
    showToast('操作失败，请重试');
  }
};

const handlePostClick = (postId) => {
  emit('post-click', postId);
};

const handleComment = (postId) => {
  router.push(`/post/${postId}`)
};

const checkScrollBottom = () => {
  if (isCheckingScroll || props.loading || !props.hasMore) return;
  isCheckingScroll = true;

  requestAnimationFrame(() => {
    const container = postListContainer.value;
    if (!container) {
      isCheckingScroll = false;
      return;
    }

    const { scrollTop, scrollHeight, clientHeight } = container;
    if (scrollHeight - scrollTop - clientHeight < 50) {
      emit('load-more');
    }
    isCheckingScroll = false;
  });
};

const setupScrollListener = () => {
  if (scrollHandler) {
    postListContainer.value.removeEventListener('scroll', scrollHandler);
  }
  scrollHandler = () => checkScrollBottom();
  if (postListContainer.value) {
    postListContainer.value.addEventListener('scroll', scrollHandler);
  }
};

onMounted(() => {
  nextTick(() => {
    if (postListContainer.value) {
      setupScrollListener();
      setTimeout(checkScrollBottom, 300);
    }
  });
});

onUnmounted(() => {
  if (scrollHandler && postListContainer.value) {
    postListContainer.value.removeEventListener('scroll', scrollHandler);
  }
});
</script>

<style scoped>
.post-list {
  background-color: var(--background);
  min-height: 100vh;
  padding-bottom: 20px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.post-card {
  margin: 15px 15px;
  background-color: var(--card-bg);
  border-radius: var(--border-radius);
  box-shadow: var(--shadow);
  transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
  padding: 16px;
}

.post-card:active {
  transform: scale(0.99);
}

.post-card :deep(.van-cell) {
  background-color: transparent;
  padding: 0;
}

.post-header {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
}

.post-user-info {
  flex: 1;
  margin-left: 15px;
}

.post-user-name {
  font-weight: 600;
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  gap: 5px;
}

.post-time {
  font-size: 0.85rem;
  color: var(--text-light);
}

.post-title {
  font-weight: 700;
  margin-bottom: 10px;
  font-size: 1.15rem;
  color: var(--text-dark);
}

.post-content {
  color: var(--text-medium);
  margin-bottom: 15px;
  line-height: 1.6;
  font-size: 1.02rem;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
  -webkit-line-clamp: 3;
}

.post-footer {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 25px;
  margin-top: 15px;
  padding-top: 10px;
  border-top: 1px solid var(--border-color);
}

.post-action {
  display: flex;
  align-items: center;
  font-size: 0.95rem;
  color: var(--text-light);
  gap: 5px;
}

.post-action:active {
  transform: scale(0.95);
}

.post-action .van-icon {
  font-size: 1.2rem;
}

.like .van-icon {
  color: #ff5000;
}

.collect .van-icon {
  color: #ffc107;
}

.loading-indicator {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px 0;
}

.no-more-data {
  text-align: center;
  color: var(--text-light);
  padding: 20px 0;
}

.empty-state {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 60vh;
  color: #ccc;
  font-size: 1rem;
}
</style>